<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=Edge,chrome=1" >
    <meta name="renderer" content="webkit">
    <link rel="shortcut icon" href="https://www.ksyun.com/assets/img/static/favicon.ico" type="image/x-icon">
    <title>h265 web player</title>
    <meta content="h265, 直播SDK，点播SDK，金山云，视频云，视频播放，KLS，KVS，Kingsoft，KingCloud, Playback, player" name="keywords">
    <meta content="h265.js是金山云的Web端视频播放器，仅支持h265视频编码和AAC音频编码的flv格式的直播和点播视频。支持IE9及以上现代浏览器。本SDK隶属于金山云视频云解决方案" name="description">
    <style>
        .mainContainer {
            display: block;
            width: 1024px;
            margin-left: auto;
            margin-right: auto;
        }

        .urlInput {
            /* display: block; */
            /* width: 100%; */
            width:920px;
            margin-left: auto;
            margin-right: auto;
            margin-top: 8px;
            margin-bottom: 8px;
        }

        .centeredAudio, .centeredVideo {
            display: block;
            width: 100%;
            /* height: auto; */
            margin-left: auto;
            margin-right: auto;
            margin-bottom: auto;
            /* display: none; */
        }

        .controls {
            display: block;
            width: 100%;
            text-align: left;
            margin-left: auto;
            margin-right: auto;
            margin-top: 8px;
            margin-bottom: 10px;
        }

        .logcatBox {
            border-color: #CCCCCC;
            font-size: 11px;
            font-family: Menlo, Consolas, monospace;
            display: block;
            width: 100%;
            text-align: left;
            margin-left: auto;
            margin-right: auto;
        }
        .options{
            margin-bottom : 6px;
            font-size : 13px;
        }
    </style>
</head>
<body>
<div class="mainContainer">
    <input name="265urlinput" class="urlInput" type="text" value="http://127.0.0.1:1554/streams/test/live1.flv"/>
    <!-- <input name="265urlinput" class="urlInput" type="text" value=""/> 196525_VtTnv_480p-->
    <canvas id="videoDisplayCanvas" width="960" height="540" style="border: 1px dashed;">
        <!-- <canvas id="videoDisplayCanvas" width="960" height="540" style="border: 1px dashed;"></canvas> -->
        Your browser is too old which doesn't support HTML5 canvas
    </canvas>
    <audio name="audioElement" class="centeredAudio" controls>
    <!-- <audio name="audioElement" class="centeredAudio" controls autoplay style="display:none;"> -->
        Your browser is too old which doesn't support HTML5 audio.
    </audio>
    <div class="controls">
        <button onclick="flv_load()">Load</button>
        <button onclick="flv_start()">Start</button>
        <button onclick="flv_pause()">Pause</button>
        <button onclick="flv_destroy()">Destroy</button>
        <input style="width:100px" type="text" name="seekpoint"/>
        <button onclick="flv_seekto()">SeekTo</button>
    </div>
    <textarea name="logcatbox" class="logcatBox" rows="10" readonly></textarea>
</div>

<script src="./h265.min.js"></script>

<script>
    var player, logcatbox = document.getElementsByName('logcatbox')[0],flvLoad = false,paused = false;
    var audioElement = document.getElementsByName('audioElement')[0];
    var urlInput = document.getElementsByName('265urlinput')[0];
    var canvas = document.getElementById('videoDisplayCanvas');
    var videoElement = document.getElementsByName('videoElement')[0];
    var baseUri = location.protocol+'//'+location.host+'/';

    function flv_load() {
        if (typeof player !== "undefined") {
            if (player != null) {
                player.destroy();
                player = null;
            }
        }

        player = h265js.createPlayer({
            isLive: false
        }, 
        {
            maxLength4ToBeDecodeQueue: 7 + 30 * 30, //待解码NALU队列最大长度 (fps * s) 7 + 30 * 30
            maxLength4ToBeRenderQueue: 200, //待渲染frame队列最大长度 (720p每帧2M，1080p每帧3M) 200
            enableYUVrender: true,
            enableSkipFrame: false, 
            disableStreamLoader: false,  
            lazyLoadMaxDuration: 3 * 60,
            seekType: 'range',
            wasmFilePath: baseUri+'demos/flv265/libqydecoder.wasm',
            url: urlInput.value,
            timeToDecideWaiting: 500,       //暂停多久算卡顿, 默认500ms
            decodingCapacityInadequateDuration: 10,  //解码能力不足持续的时间，默认10s
            threshold4decodingCamacityIndequte: 0.8,     //实际fps统计值／码流fps < threshold4decodingCamacityIndequte, 持续decodingCapacityInadequateDuration秒，则判定为解码能力不足
            bufferTime: 500,     //启播前缓冲视频时长（ms）
            token: '30ed827e0ccbdbf5642a3f0f8f092f12'
        },{
            audioElement: audioElement,
            canvas: canvas,
            videoElement: videoElement
        });
        
        if (player) {
            
            player.on(h265js.Events.READY, function(event, data){
                // console.warn('ready: ', event, data);
                flvLoad = true;
                paused = false;
                player.load();
                //safari浏览器audio标签需要主动触发才可播放
                // if (browser_detect('safari')) {
                //     player.play();
                // }

                // for (event in h265js.Events) {
                //     player.on(h265js.Events[event], function(e, data) {
                //         console.log(data);
                //         if (h265js.Events[event] == h265js.Events.ERROR && data) {
                //             console.log(data.type, data.detail, data.info);
                //         }
                //     });
                // }
            });
            
            // player.on(h265js.Events.LOADSTART, function(event, data){
            //     console.log('loadStart: ', event, data);
            // });
            player.on(h265js.Events.MEDIAINFO, function(event, data){
                console.warn('mediaInfo: ', event, data);
            });
            // player.on(h265js.Events.VOLUMECHANGE, function(event, data){
            //     console.log('volumechange: ', event, data);
            // });
            player.on(h265js.Events.ERROR, function(event, data){
                console.warn('error: ', event, data.type, data.detail, data.info, data.info.code, data.info.msg);
            });
            // player.on(h265js.Events.WARNING, function(event, data){
            //     console.warn('warning: ', event, data);
            // });
            // player.on(h265js.Events.STATISTICSINFO, function(event, data){
            //     console.log('statisticsInfo: ', event, data);
            // });
            player.on(h265js.Events.WAITING, function(event, data){
                console.warn('waiting: ', event, data);
            });
            player.on(h265js.Events.PLAYING, function(event, data){
                console.warn('playing: ', event, data);
            });

            // player.on(h265js.Events.LOADEDEND, function(event, data){
            //     console.log('loadedEnd: ', event, data);
            // });
            // player.on(h265js.Events.PLAY, function(event, data){
            //     console.log('play: ', event, data);
            // });
            // player.on(h265js.Events.PAUSE, function(event, data){
            //     console.log('pause: ', event, data);
            // });
            player.on(h265js.Events.RELOAD, function(event, data){
                console.warn('reload: ', event, data);
            });
        }
    }

    function flv_start() {
        if (player) {
            player.play();
        }
    }

    function flv_pause() {
        if (player) {
            player.pause();
            paused = true;
        }
    }

    function flv_destroy() {
        if (player) {
            setTimeout(function() {
                player.destroy();
                player = null;
            }, 500);
        } 
        flvLoad = false;
    }

    function flv_seekto() {
        var input = document.getElementsByName('seekpoint')[0];
        player.currentTime = parseFloat(input.value);
    }

    function getUrlParam(key, defaultValue) {
        var pageUrl = window.location.search.substring(1);
        var pairs = pageUrl.split('&');
        for (var i = 0; i < pairs.length; i++) {
            var keyAndValue = pairs[i].split('=');
            if (keyAndValue[0] === key) {
                return keyAndValue[1];
            }
        }
        return defaultValue;
    }

    function browser_detect(name) {
        // Opera 8.0+
        var isOpera = (!!window.opr && !!opr.addons) || !!window.opera || navigator.userAgent.indexOf(' OPR/') >= 0;

        // Firefox 1.0+
        var isFirefox = typeof InstallTrigger !== 'undefined';

        // Safari 3.0+ "[object HTMLElementConstructor]" 
        var isSafari = /constructor/i.test(window.HTMLElement) || (function (p) { return p.toString() === "[object SafariRemoteNotification]"; })(!window['safari'] || safari.pushNotification);

        // Internet Explorer 6-11
        var isIE = /*@cc_on!@*/false || !!document.documentMode;

        // Edge 20+
        var isEdge = !isIE && !!window.StyleMedia;

        // Chrome 1+
        var isChrome = !!window.chrome && !!window.chrome.webstore;

        // Blink engine detection
        var isBlink = (isChrome || isOpera) && !!window.CSS;

        switch (name) {
            case 'safari':
                return isSafari;
            case 'chrome':
                return isChrome;
            case 'opera':
                return isOpera;
            case 'firefox':
                return isFirefox;
            default:
                return '请输入要检测的浏览器名称';
        }
    }

    h265js.LoggingControl.addLogListener(function(type, str) {
        logcatbox.value = logcatbox.value + str + '\n';
        logcatbox.scrollTop = logcatbox.scrollHeight;
    });

    document.addEventListener('DOMContentLoaded', function () {
        // flv_load();
    });

    // 各种浏览器兼容
    var state, visibilityChange; 
    if (typeof document.hidden !== "undefined") {  //normal
        visibilityChange = "visibilitychange";
        state = "visibilityState";
    } else if (typeof document.mozHidden !== "undefined") {  //moz
        visibilityChange = "mozvisibilitychange";
        state = "mozVisibilityState";
    } else if (typeof document.msHidden !== "undefined") {   //ms
        visibilityChange = "msvisibilitychange";
        state = "msVisibilityState";
    } else if (typeof document.webkitHidden !== "undefined") {  //webkit
        visibilityChange = "webkitvisibilitychange";
        state = "webkitVisibilityState";
    }

    document.addEventListener(visibilityChange, function() {
        if (!browser_detect('opera')) {
            if (document[state] === "visible") {
                if (flvLoad) {
                    flv_load();
                }
            } else {
                if (flvLoad) {
                    flv_destroy();
                    flvLoad = true;
                }
            }
        }
    });
    // window.onload = function() {
    //     this.flv_load();
    // }
</script>
</body>
</html>